{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2.2. Using the latest features of Python 3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:46:03.177194Z",
     "start_time": "2023-10-20T12:46:02.963615Z"
    }
   },
   "outputs": [],
   "source": [
    "my_list = list(range(10))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:46:03.177518Z",
     "start_time": "2023-10-20T12:46:02.968184Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n"
     ]
    }
   ],
   "source": [
    "print(my_list)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:46:03.177654Z",
     "start_time": "2023-10-20T12:46:02.971915Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 2 3 4 5 6 7 8 9\n"
     ]
    }
   ],
   "source": [
    "print(*my_list)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:46:03.177851Z",
     "start_time": "2023-10-20T12:46:02.974816Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 = 45"
     ]
    }
   ],
   "source": [
    "print(*my_list, sep=\" + \", end=\" = %d\" % sum(my_list))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:46:03.177912Z",
     "start_time": "2023-10-20T12:46:02.981478Z"
    }
   },
   "outputs": [],
   "source": [
    "first, second, *rest, last = my_list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:46:03.178023Z",
     "start_time": "2023-10-20T12:46:02.984860Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 9\n"
     ]
    }
   ],
   "source": [
    "print(first, second, last)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:46:03.178172Z",
     "start_time": "2023-10-20T12:46:02.991013Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "[2, 3, 4, 5, 6, 7, 8]"
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rest"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:46:03.178306Z",
     "start_time": "2023-10-20T12:46:02.995853Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "1.0"
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from math import pi, cos\n",
    "α = 2\n",
    "π = pi\n",
    "cos(α * π)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:46:03.178430Z",
     "start_time": "2023-10-20T12:46:03.000997Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "'The sum of 1 and 2 is 3'"
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a, b = 1, 2\n",
    "f\"The sum of {a} and {b} is {a + b}\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:46:03.178491Z",
     "start_time": "2023-10-20T12:46:03.004205Z"
    }
   },
   "outputs": [],
   "source": [
    "def kinetic_energy(mass: 'kg',\n",
    "                   velocity: 'm/s') -> 'J':\n",
    "    \"\"\"The annotations serve here as documentation.\"\"\"\n",
    "    return .5 * mass * velocity ** 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:46:03.178590Z",
     "start_time": "2023-10-20T12:46:03.008958Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "mass is in kg, velocity is in m/s, return is in J\n"
     ]
    }
   ],
   "source": [
    "annotations = kinetic_energy.__annotations__\n",
    "print(*(f\"{key} is in {value}\"\n",
    "        for key, value in annotations.items()),\n",
    "      sep=\", \")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:46:03.178647Z",
     "start_time": "2023-10-20T12:46:03.011743Z"
    }
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "M = np.array([[0, 1], [1, 0]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:46:03.178792Z",
     "start_time": "2023-10-20T12:46:03.108468Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "array([[0, 1],\n       [1, 0]])"
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "M * M"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:46:03.179141Z",
     "start_time": "2023-10-20T12:46:03.122256Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "array([[1, 0],\n       [0, 1]])"
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "M @ M"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:46:03.179218Z",
     "start_time": "2023-10-20T12:46:03.130395Z"
    }
   },
   "outputs": [],
   "source": [
    "def gen1():\n",
    "    for i in range(5):\n",
    "        for j in range(i):\n",
    "            yield j"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:46:03.179280Z",
     "start_time": "2023-10-20T12:46:03.137566Z"
    }
   },
   "outputs": [],
   "source": [
    "def gen2():\n",
    "    for i in range(5):\n",
    "        yield from range(i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:46:03.179416Z",
     "start_time": "2023-10-20T12:46:03.144350Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "[0, 0, 1, 0, 1, 2, 0, 1, 2, 3]"
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(gen1())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:46:03.179543Z",
     "start_time": "2023-10-20T12:46:03.150672Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "[0, 0, 1, 0, 1, 2, 0, 1, 2, 3]"
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(gen2())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:46:03.179971Z",
     "start_time": "2023-10-20T12:46:03.157503Z"
    }
   },
   "outputs": [],
   "source": [
    "import time\n",
    "\n",
    "def f1(x):\n",
    "    time.sleep(1)\n",
    "    return x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:46:04.170030Z",
     "start_time": "2023-10-20T12:46:03.164311Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n"
     ]
    }
   ],
   "source": [
    "%timeit -n1 -r1 f1(0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:46:05.177834Z",
     "start_time": "2023-10-20T12:46:04.168539Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n"
     ]
    }
   ],
   "source": [
    "%timeit -n1 -r1 f1(0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:46:05.182136Z",
     "start_time": "2023-10-20T12:46:05.179182Z"
    }
   },
   "outputs": [],
   "source": [
    "from functools import lru_cache\n",
    "\n",
    "@lru_cache(maxsize=32)  # keep the latest 32 calls\n",
    "def f2(x):\n",
    "    time.sleep(1)\n",
    "    return x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:46:06.196985Z",
     "start_time": "2023-10-20T12:46:05.184215Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.01 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n"
     ]
    }
   ],
   "source": [
    "%timeit -n1 -r1 f2(0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:46:06.201702Z",
     "start_time": "2023-10-20T12:46:06.198477Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.29 µs ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n"
     ]
    }
   ],
   "source": [
    "%timeit -n1 -r1 f2(0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:46:06.221552Z",
     "start_time": "2023-10-20T12:46:06.203595Z"
    }
   },
   "outputs": [],
   "source": [
    "from pathlib import Path"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:46:06.221827Z",
     "start_time": "2023-10-20T12:46:06.207310Z"
    }
   },
   "outputs": [],
   "source": [
    "p = Path('.')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:46:06.240011Z",
     "start_time": "2023-10-20T12:46:06.211889Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "[]"
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sorted(p.glob('*.md'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:46:06.494880Z",
     "start_time": "2023-10-20T12:46:06.215247Z"
    }
   },
   "outputs": [
    {
     "ename": "IndexError",
     "evalue": "list index out of range",
     "output_type": "error",
     "traceback": [
      "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[0;31mIndexError\u001B[0m                                Traceback (most recent call last)",
      "Cell \u001B[0;32mIn[28], line 1\u001B[0m\n\u001B[0;32m----> 1\u001B[0m \u001B[43m_\u001B[49m\u001B[43m[\u001B[49m\u001B[38;5;241;43m0\u001B[39;49m\u001B[43m]\u001B[49m\u001B[38;5;241m.\u001B[39mread_text()\n",
      "\u001B[0;31mIndexError\u001B[0m: list index out of range"
     ]
    }
   ],
   "source": [
    "_[0].read_text()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "start_time": "2023-10-20T12:46:06.489891Z"
    }
   },
   "outputs": [],
   "source": [
    "[d for d in p.iterdir() if d.is_dir()]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "start_time": "2023-10-20T12:46:06.491709Z"
    }
   },
   "outputs": [],
   "source": [
    "list((p / 'images').iterdir())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "start_time": "2023-10-20T12:46:06.492947Z"
    }
   },
   "outputs": [],
   "source": [
    "import random as r\n",
    "import statistics as st"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "start_time": "2023-10-20T12:46:06.493846Z"
    }
   },
   "outputs": [],
   "source": [
    "my_list = [r.normalvariate(0, 1)\n",
    "           for _ in range(100000)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "start_time": "2023-10-20T12:46:06.494799Z"
    }
   },
   "outputs": [],
   "source": [
    "print(st.mean(my_list),\n",
    "      st.median(my_list),\n",
    "      st.stdev(my_list),\n",
    "      )"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "name": "python3",
   "language": "python",
   "display_name": "Python 3 (ipykernel)"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
